﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography;
using System.Text;

namespace Zack.Tools.Extension
{
    public static class StringExtension
    {
        /// <summary>
        /// 返回字符串字节长度,汉字占2位
        /// </summary>
        /// <param name="source"></param>
        /// <returns></returns>
        public static int StringLength(this string source)
        {
            var bytes = Encoding.Unicode.GetBytes(source);
            int count = 0;
            for (int i = 1; i < bytes.Length; i+=2)
            {
                count += bytes[i] == 0 ? 1 : 2;
            }
            return count;
        }

        #region Is

        /// <summary>
        /// 判断字符串是否为空或null
        /// </summary>
        /// <param name="source"></param>
        /// <returns></returns>
        public static bool IsNullOrEmpty(this string source)
        {
            return string.IsNullOrEmpty(source);
        }

        /// <summary>
        /// 判断字符串是否不是空或null
        /// </summary>
        /// <param name="source"></param>
        /// <returns></returns>
        public static bool IsNotNullOrEmpty(this string source)
        {
            return !string.IsNullOrEmpty(source);
        }

        /// <summary>
        /// 判断是否为int
        /// </summary>
        /// <param name="source"></param>
        /// <returns></returns>
        public static bool IsInt(this string source)
        {
            int tmp;
            return int.TryParse(source, out tmp);
        }

        /// <summary>
        /// 判断是否为float
        /// </summary>
        /// <param name="source"></param>
        /// <returns></returns>
        public static bool IsFloat(this string source)
        {
            float tmp;
            return float.TryParse(source, out tmp);
        }

        /// <summary>
        /// 判断是否为double
        /// </summary>
        /// <param name="source"></param>
        /// <returns></returns>
        public static bool IsDouble(this string source)
        {
            double tmp;
            return double.TryParse(source, out tmp);
        }

        #endregion

        #region To

        /// <summary>
        /// 转成成double型,如果不能转换返回-1
        /// </summary>
        /// <param name="source"></param>
        /// <returns></returns>
        public static double ToDouble(this string source)
        {
            return source.ToDouble(-1.0);
        }
        /// <summary>
        /// 转成成double型,如果不能转换返回defaultValue
        /// </summary>
        /// <param name="source"></param>
        /// <param name="defaultValue">不能转换时返回默认值</param>
        /// <returns></returns>
        public static double ToDouble(this string source, double defaultValue)
        {
            double tmp;
            if (!double.TryParse(source, out tmp))
            {
                tmp = defaultValue;
            }
            return tmp;
        }

        /// <summary>
        /// 转成成float型,如果不能转换返回-1
        /// </summary>
        /// <param name="source"></param>
        /// <returns></returns>
        public static float ToFloat(this string source)
        {
            return source.ToFloat(-1f);
        }
        /// <summary>
        /// 转成成float型,如果不能转换返回defaultValue
        /// </summary>
        /// <param name="source"></param>
        /// <param name="defaultValue">不能转换时返回默认值</param>
        /// <returns></returns>
        public static float ToFloat(this string source, float defaultValue)
        {
            float tmp;
            if (!float.TryParse(source, out tmp))
            {
                tmp = defaultValue;
            }
            return tmp;
        }

        /// <summary>
        /// 转成成int型,如果不能转换返回-1
        /// </summary>
        /// <param name="source"></param>
        /// <returns></returns>
        public static int ToInt(this string source)
        {
            return source.ToInt(-1);
        }
        /// <summary>
        /// 转成成int型,如果不能转换返回defaultValue
        /// </summary>
        /// <param name="source"></param>
        /// <param name="defaultValue">不能转换时返回默认值</param>
        /// <returns></returns>
        public static int ToInt(this string source,int defaultValue)
        {
            int tmp;
            if (!int.TryParse(source, out tmp))
            {
                tmp = defaultValue;
            }
            return tmp;
        }

        /// <summary>
        /// 将字符转换成32位16进制的MD5加密字符
        /// </summary>
        /// <param name="source"></param>
        /// <returns></returns>
        public static string ToMD5(this string source)
        {
            string pwd = string.Empty;
            MD5 md5 = MD5.Create(); //实例化一个md5对像
            // 加密后是一个字节类型的数组，这里要注意编码UTF8/Unicode等的选择　
            byte[] s = md5.ComputeHash(Encoding.UTF8.GetBytes(source));
            // 通过使用循环，将字节类型的数组转换为字符串，此字符串是常规字符格式化所得
            for (int i = 0; i < s.Length; i++)
            {
                //将得到的字符串使用十六进制类型格式。格式后的字符是小写的字母，如果使用大写（X）则格式后的字符是大写字符
                pwd += s[i].ToString("x2");
            }
            return pwd;
        }

        #endregion
    }
}
